using namespace std;

#include<stdio.h>
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdlib>
#include"random_access.hpp"

random_access_t::random_access_t(const char * filename, off_t rows,off_t cols){
  //printf("Size of off_t %d\n",sizeof(off_t));
  //ifs.open(filename,ios::in|ios::binary);
  //if (!ifs.is_open()){
    //cerr<<"Could not open "<<filename<<endl;
    //exit(1);
  //}
  pFile = fopen(filename,"rb");
  if(pFile==NULL){
    cerr<<"Could not open "<<filename<<endl;
    exit(1);
  }
  this->rows = rows;
  this->cols = cols;
  //cerr<<"Initialized Random Access on "<<filename<<" with "<<rows<<" rows and "<<cols<<" columns.\n";
  this->floatlen = sizeof(float);
}

random_access_t::~random_access_t(){
  //ifs.close();
  fclose(pFile);
}

void random_access_t::extract_vec(off_t row, unsigned int len, float * vec){
  //unsigned int charlen = floatlen*len;
  char * buffer = reinterpret_cast<char *>(vec);
  off_t pos = floatlen*(row*cols);
  int rc = fseeko(pFile,pos,SEEK_SET);
  if(rc!=0) perror("Seek error\n");
  off_t tell = ftello(pFile);
  if(tell!=pos){
    cerr<<"Tell does not match seek in extract_vec!\n";
    cerr<<"Tell is "<<tell<<endl;
    cerr<<"Error code is "<<rc<<endl;
    exit(1);
  }
  fread(buffer,floatlen,len,pFile);
  vec = reinterpret_cast<float * >(buffer);
}


void random_access_t::marshall(ostream & os, float * vec, int len){
  int floatlen = sizeof(float);
  char * charvec = reinterpret_cast<char *>(vec);
  long unsigned int outlen = floatlen * len;
  os.write(charvec,outlen);
}


#ifdef _UNIT_TEST
int main(int argc,char * argv[]){
  if(argc<6) {
    cerr<<"Usage: <filename> <input rows> <input cols> <test row> <test col>\n";
    return 1;
  }
  int arg=0;
  const char * filename=argv[++arg];
  off_t rows = atoi(argv[++arg]);
  off_t cols = atoi(argv[++arg]);
  off_t testrow = atoi(argv[++arg]);
  off_t testcol = atoi(argv[++arg]);
  random_access_t access(filename,rows,cols);
  float val = access.extract_val(testrow,testcol);
  cout<<"Value at "<<testrow<<","<<testcol<<": "<<val<<endl;
  //float * vec = new float[cols];
  //access.extract_vec(testrow,cols,vec);
  //cout<<"Vector at row: "<<testrow<<":\n";
  for(off_t i=0;i<cols;++i){
    //if(i) cout<<" ";
    //cout<<vec[i];
  }
  //cout<<endl;
  //delete[] vec;
  
  
  return 0;
}
#endif
